import queue
import random
import threading
import time
import PCBD
import gptApi
userInfoList = dict()
userRespList = dict()
userEventList = dict()
userDealList = queue.Queue()
userDoneList = queue.Queue()
hasTodo = threading.Event()
aliyunOn = False
def handle_client(client_socket, addr):
    # 发送欢迎消息给客户端
    message = "欢迎来到服务器！".encode()
    client_socket.send(message)
    recv = threading.Thread(target=client_receiver, args=(client_socket, addr))
    send = threading.Thread(target=client_sender, args=(client_socket,addr,threading.Event()))
    recv.start()
    send.start()

def handle_aliyun(client_socket,addr):
    # 发送欢迎消息给客户端
    message = "欢迎来到服务器！".encode()
    client_socket.send(message)
    recv = threading.Thread(target=aliyun_receiver, args=(client_socket, addr))
    send = threading.Thread(target=aliyun_sender, args=(client_socket,addr))
    recv.start()
    send.start()


#一个负责用户消息接收的线程
def client_receiver(client_socket,addr):
    global userInfoList
    global userDealList
    global aliyunOn
    global hasTodo
    userInfoList[addr] = queue.Queue()
    while True:
        data = client_socket.recv(1024)
        #接收信息
        print('收到用户{}发送的信息:{}'.format(addr,data.decode("utf-8")))
        if data.decode("utf-8") == 'exit' or data.decode() == '':
            print("用户{}断片了".format(addr))
            break
        if not aliyunOn:
            client_socket.send("aliyun is not active".encode("utf-8"))
            continue
        userInfoList[addr].put(data)
        #告诉aliyun的进程这个需要处理
        userDealList.put(addr)
        #设置事件
        hasTodo.set()
    client_socket.close()

def client_sender(client_socket,addr,E):
    global userRespList
    global userEventList
    userRespList[addr] = queue.Queue()
    userEventList[addr] = E
    while True:
        #如果没有返回消息则等待
        if userRespList[addr].empty():
            time.sleep(0.5)
            continue
        #获取返回消息
        info = userRespList[addr].get()
        print("给{}发送消息".format(addr,info.decode("utf-8")))
        #发送返回消息
        try:
            client_socket.send(info)
        except ConnectionResetError :
            aliyunOn = False
            E.clear()
            break
        E.clear()
    client_socket.close()


def aliyun_sender(client_socket, addr):
    # 发送欢迎消息给客户端
    message = "欢迎来到服务器！".encode()
    client_socket.send(message)
    global userDealList
    global aliyunOn
    global userInfoList
    global userDoneList
    aliyunOn = True
    while True:
        #如果没有需要处理的请求，等待
        if userDealList.empty():hasTodo.wait()
        #获取请求的ip地址
        Uadd = userDealList.get()
        userDoneList.put(Uadd)
        #向阿里云发送请求
        try:
            client_socket.send(userInfoList[Uadd].get())
        except (ConnectionResetError,OSError):
            aliyunOn = False
            E.clear()
            break
        #给接收进程告知这是来自哪个ip的请求

    client_socket.close()

def aliyun_receiver(client_socket,addr):
    global userEventList
    global userRespList
    global userDoneList
    global aliyunOn
    while True:
        #接收数据
        data = client_socket.recv(1024)
        if data.decode("utf-8") == '':
            #对所有用户发送已经断开的消息
            for d in userRespList:
                userRespList[d].put("阿里云断开了".encode("utf-8"))
            print("阿里云已经断开了")
            aliyunOn =False
            break
        print("收到返回信息{}".format(data.decode()))
        #这是哪个ip发送的请求
        if userDoneList.empty():continue
        Uadd = userDoneList.get()
        #对应ip的消息队列添加返回数据
        userRespList[Uadd].put(data)
        #通知对应的线程已收到回应
        #userEventList[userDoneList.get()].set()
    client_socket.close()

#阿里云自动收发:
def aliyun_auto(client_socket,addr):
    while True:
        client_socket.send("给我发题目！".encode())
        data = client_socket.recv(1024).decode()
        PCBD.addProblem(data)
def aliyun_auto_Complementary(client_socket,addr):
    while True:
        client_socket.send("给我发题目！".encode())
        data = client_socket.recv(1024).decode()
        complementary_data = gptApi.use_Api(data)
        print(complementary_data)
        PCBD.addComplementaryProblem(complementary_data['tags'], complementary_data['content'])
def client_from_database(client_socket,addr):
    while True:
        try :
            mes = client_socket.recv(1024)
        except ConnectionAbortedError:
            print("用户{}断片了".format(addr))
            break
        if mes == "":
            print("用户{}断片了".format(addr))
            break
        problem = PCBD.getProblem(random.randint(1,10))
        rtn = gptApi.use_Api(problem)
        client_socket.send(rtn.encode())
    client_socket.close()
#PCDB↓
